Writing Testsuites

[ Start > PikeDevel > Writing Testsuites ] [ Edit this Page | Show Page Versions | Show Formatted ]


Pike includes a set of scripts to generate and run testsuites. While the primary purpose of these scripts is to test the Pike interpreter itself, you can easily use them to test your own code.

This document describes the tools, as well as the syntax for writing tests.

1 Testing tools

The two tools that are included with Pike are called mktestsuite and test_pike.

__mktestsuite__

The mktestsuite script is a simple shell script that uses M4 to convert a testsuite input file into a testsuite that can be run by test_pike.pike. This script is found in $PIKE/include/pike.

~~Usage:~~

{code}
mktestsuite testsuite.in > testsuite
{code}

The input file is simply a series of test invocations; any code outside of a test invocation will be ignored and will not appear in the final testsuite file.

__test_pike__

The most important part of the regression testing infrastructure is ~~test_pike~~, which is the pike script that performs the actual testing. Included in $PIKE/include/pike for Pike releases before 7.7, and as the builtin tool ~~pike -x test_pike~~ in releases 7.7 and higher, test_pike includes a large number of options for performing testing.

~~Usage:~~

{code}
  pike test_pike testuitefile
{code}

test_pike also accepts a number of arguments, which you can review by passing the "\-\-help"" argument to the script.

1 Writing testsuites

The easiest way to generate a testsuite that can be run by test_pike is to use the mktestsuite script. mktestsuite uses M4 to perform macro substitution on your input test file. By using this preprocessor, you have access to a number of test types, which are listed below.

The format of a testsuite that uses this approach simply consists of a set of tests, listed in the order they are to be run.

~~A Simple Example:~~

{code}
test_true(1)
test_false(0)
// this next test will fail
test_false(-1)
{code}

~~Running our testsuite:~~

{code}
/usr/local/pike/7.6.50/include/pike/mktestsuite tests.in > tests
/usr/local/pike/7.6.50/include/pike/test_pike.pike tests
Doing tests in tests (3 tests)
tests.in:4: Test 3 (shift 0) (CRNL) failed.
  1: mixed a() { return -1; }
  2:

o->a(): -1

Failed tests: 1.
Total tests: 3  (0 tests skipped)
{code}

Many options are available from within the test harness, be sure to check them out by using the "\-\-help" option.

1 Available test types

In general, there are two forms of each type of test; one takes as its argument a set of statements that when run, will be placed within a function body and run. The other, denoted with a ~~_any~~ suffix, accepts as its argument(s) any block of Pike code, such as class definitions and multiple function definitions.

__test_any__

~~Usage:~~

{code}
test_any([[a]], b)
{code}

parameter __a__: a block of code (classes and functions) that return a value

parameter __b__: a value or expression

 does the return value of the block "a" equal the value b, as in ==?

~~Example:~~ 

{code}
test_any([[
  int f (int i) {i = 0; return i;};
  return f (1);
]],0)
{code}


__test_any_equal__

~~Usage:~~

{code}
test_any_equal([[a]], b)
{code}

parameter __a__: a block of code (classes and functions) that return a value

parameter __b__: a value or expression

does the return value of the block "a" equal the value b, as in equal()? useful for checking reference types when you want to check for  the sameness of values

~~Example:~~ 

{code}
test_any_equal([[
  class Foo {int foo();};
  return indices(Foo());
]], ({"foo"}))
{code}


__test_eq__

~~Usage:~~

{code}
test_eq(a, b)
{code}

parameter __a__: a value or expression

parameter __b__: a value or expression

are a and b the same item, as in ==?

~~Example:~~

{code}
test_eq('\u117f', 0x117f)
{code}

__test_equal__

~~Usage:~~

{code}
test_equal(a, b)
{code}

parameter __a__: a value or expression

parameter __b__: a value or expression

are a and b equal, as in equal()? useful for checking reference types when you want to check for  the sameness of values

~~Example:~~

{code}
test_equal(mtest_m,copy_value(mtest_m))
{code}

__test_do__

~~Usage:~~

{code}
test_do(a)
{code}

parameter __a__: a function body

does a run?

~~Example:~~

{code}
test_do([[
  void foo (int i) {
    multiset res = (<>);
    if (i) res = res;
  };
  foo (1);
]])
{code}



__test_true__

~~Usage:~~

{code}
test_true(a)
{code}

parameter __a__: a value or expression

does a evaluate to true (ie not integer zero (0) )

~~Example:~~

{code}
test_true("A" == upper_case("a"))
{code}

__test_false__

~~Usage:~~

{code}
test_false(a)
{code}

parameter __a__: a value or expression

does a evaluate to false (ie an integer zero (0))

~~Example:~~

{code}
test_false("A" == "a")
{code}


__test_compile__

~~Usage:~~

{code}
test_compile([[a]])
{code}

parameter __a__: one or more statements to compile, these statements will be placed inside a function body.

does the code compile?

~~Example:~~

{code}
test_compile([[ Stdio.File foo=Stdio.File(); ]])
{code}

__test_compile_any__

~~Usage:~~

{code}
test_compile_any([[a]])
{code}

parameter __a__: a code block (functions and classes) to compile

does the code compile?

~~Example:~~

{code}
test_compile_any([[
  void foo()
  {
    Stdio.File bar(int x, int y)
    {
      return 0;
    };
  }
]])
{code}

__test_compile_error__

~~Usage:~~

{code}
test_compile_error([[a]])
{code}

parameter __a__: one or more statements to compile (these statements will be placed inside a function body).

does the code fail to compile?

~~Example:~~

{code}
test_compile_error([[ string a="x"; int b; b="x"*17; ]])
{code}


__test_compile_error_any__

~~Usage:~~

{code}
test_compile_error_any([[a]])
{code}

parameter __a__: a code block (functions and classes) to compile

does the code fail to compile?

~~Example:~~

{code}
test_compile_error_any([[
 mixed foo;
 mapping query_variables() { return ([]); };
 mixed foo(mixed bar) { return 1/foo; }
]])
{code}

__test_compile_warning__

~~Usage:~~

{code}
test_compile_warning([[a]])
{code}

parameter __a__: one or more statements to compile (these statements will be placed inside a function body).

does the code compile, generating a warning?

~~Example:~~

{code}
test_compile_warning([[ int *a ]])
{code}


__test_compile_warning_any__

~~Usage:~~

{code}
test_compile_warning_any([[a]])
{code}

parameter __a__: a code block (functions and classes) to compile

does the code compile, but generate warnings?

~~Example:~~

{code}
test_compile_warning_any([[
#pragma strict_types 

class foo(string|int a)
{
  void bar()
  {
    int b = a; 
  }
}

object a = foo(1);

]])
{code}

__test_eval_error__

~~Usage:~~

{code}
test_eval_error([[a]])
{code}

parameter __a__: one or more statements to compile (these statements will be placed inside a function body).

does the code throw a runtime error when evaluated?

~~Example:~~

{code}
test_eval_error([[ class Z { int destroy() { return 1/y; } }(); ]])
{code}


__test_define_program__

~~Usage:~~

{code}
test_define_program(a, [[b]])
{code}

parameter __a__: a name for the program to be defined as
parameter __b__: a class body

define a class for use in later tests

~~Example:~~

{code}
test_define_program(bar,[[ int a(){ return 1; } ]])
{code}

__test_program__

~~Usage:~~

{code}
test_program([[a]])
{code}

parameter __a__: a class definition which has an member function a() which returns an int. this method should return a "true" value for the test to succeed.

~~Example:~~

{code}
// we use the program "bar", which was defined 
//previously through the use of test_define_program
test_program([[ inherit bar; ]])
{code}

__test_program_eq__

~~Usage:~~

{code}
test_program_eq([[a]], b)
{code}

parameter __a__: a program definition which has a member function "a" which returns a value

parameter __b__: a value or expression

does the evaluation of function "a()" in parameter a equal the value "b", as in  ==? 

~~Example:~~

{code}
test_program_eq([[
  constant x = X;
  class X {constant c = "right";}

  constant y = Y;
  class Y {constant c = "wrong";}

  string a()
  {
    return ::`[]("x")->c;
  }
]], "right")
{code}

__test_program_equal__

{code}
test_program_equal([[a]], b)
{code}

parameter __a__: a program definition which has a member function "a" which returns a value

parameter __b__: a value or expression

does the evaluation of function "a()" in parameter a equal the value "b", as in  equal()? 

~~Example:~~

{code}
test_program_eq([[
  constant x = X;
  class X {constant c = ({"right"});}

  constant y = Y;
  class Y {constant c = ({"wrong"});}

  string a()
  {
    return ::`[]("x")->c;
  }
]], ({"right"}))
{code}

other testsuite functions:

__test_tests__

~~Usage:~~

{code}
test_tests([[a]])
{code}

parameter __a__: a class definition which has a member function a, which returns an array with 2 integer elements: a[0] is the number of passed tests, and a[1] is the number of failures.

perform a series of tests and return the resulting number of successes and failures.

__test_do__

~~Usage:~~

{code}
test_do(a)
{code}

parameter __a__: an expression which will be evaluated.

this "test" is useful for performing operations; as the test is merely run, but no result is checked.

1 Other resources

- {link:Pike Test Suite, from the Pike Reference Manual|http://pike.ida.liu.se/generated/manual/ref/chapter_19.html}

Powered by PikeWiki2

 
gotpike.org | Copyright © 2004 - 2009 | Pike is a trademark of Department of Computer and Information Science, Linköping University